package com.education.welco.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.education.common.utils.DateUtil;
import com.education.common.utils.StringUtils;
import com.education.welco.enums.DbEnumsUtil;
import com.education.welco.mapper.*;
import com.education.welco.pojo.OrderPaper;
import com.education.welco.pojo.TClass;
import com.education.welco.pojo.TSchool;
import com.education.welco.pojo.dto.LearningStatisticsDto;
import com.education.welco.pojo.vo.*;
import com.education.welco.service.OrderPaperAnalysisService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * zcp
 * 试卷分析
 * 2022/10/21
 */
@Service
public class OrderPaperAnalysisServiceImpl implements OrderPaperAnalysisService {

    @Autowired
    private OrderPaperAnalysisMapper orderPaperAnalysisMapper;
    @Autowired
    private OrderPaperMapper orderPaperMapper;
    @Autowired
    private TStudentMapper tStudentMapper;
    @Autowired
    private TSchoolMapper tSchoolMapper;
    @Autowired
    private OrderWrongAnswerMapper OrderWrongAnswerMapper;

    private static final BigDecimal zero = new BigDecimal("0");
    private static final BigDecimal twenty = new BigDecimal("20");
    private static final BigDecimal twentyOne = new BigDecimal("21");
    private static final BigDecimal fifty = new BigDecimal("50");
    private static final BigDecimal fiftyOne = new BigDecimal("51");
    private static final BigDecimal fiftyNine = new BigDecimal("59");
    private static final BigDecimal sixty = new BigDecimal("60");
    private static final BigDecimal eighty = new BigDecimal("80");
    private static final BigDecimal eightyOne = new BigDecimal("81");
    private static final BigDecimal ninety = new BigDecimal("90");
    private static final BigDecimal ninetyOne = new BigDecimal("91");
    private static final BigDecimal ninetyNine = new BigDecimal("99");
    private static final BigDecimal oneHundred = new BigDecimal("100");
    private static final String str1 = "0-59";
    private static final String str2 = "60-80";
    private static final String str3 = "81-90";
    private static final String str4 = "91-99";
    private static final String str5 = "100";
    private static final String progressStr1 = "0-20%";
    private static final String progressStr2 = "21%-50%";
    private static final String progressStr3 = "51%-80%";
    private static final String progressStr4 = "81%-100%";
    private static final DecimalFormat df = new DecimalFormat("0.00");
    private static final int timeLimit = 120;

    private static final BigDecimal zero_0 = new BigDecimal("0.00");


    //平均分，总分，最高分，最低分，平均作答时长，及格率，各个分段人数
    //1 0-59分段
    //2 60-80分段
    //3 81-90分段
    //4 91-99分段
    //5 100分
    @Override
    public Map<String, Object> summary(Integer paperId) {
        Map<String, Object> map = new HashMap<>();
        //存储答题详细信息
        List<UserPaperAnswerInfo> answerInfoList = new ArrayList<UserPaperAnswerInfo>();

        //获取试卷信息 拿总分
        OrderPaper orderPaper = orderPaperMapper.selectOrderPaperById(paperId);
        BigDecimal passScore = new BigDecimal(orderPaper.getPassscore());
        map.put("totalScore", orderPaper.getScore());
        //获取班级信息
        List<TClass> tClasses = orderPaperMapper.selectClassByTopCatalogId(orderPaper.getTopCatalogId());
        //获取学生人数
        Integer stuNum = tStudentMapper
                .selectStudentNumByClassId(tClasses.stream().map(TClass::getId).collect(Collectors.toList()));
        //获取学生答题试卷信息
        Map<String, Object> infoMap = orderPaperAnalysisMapper.getUserPaperInfo(paperId, stuNum, passScore);
        // 根据分数降序排序 取最高最低分
        map.put("maxScore", infoMap.get("maxScore"));
        map.put("minScore", infoMap.get("minScore"));
        //求和拿平均分 四舍五入保留2位小数
        map.put("averageScore", df.format(infoMap.get("averageScore")));

        //实考人数 应考人数
        map.put("stuNumRealTest", infoMap.get("stuNumRealTest"));
        map.put("stuNumShouldTest", stuNum);

        //平均时长 通过率
        map.put("averageTime", df.format((float) Integer.valueOf(String.valueOf(infoMap.get("sumTime"))) / 1000 / 60 / stuNum));
        String passRate = df.format((float) Integer.valueOf(String.valueOf(infoMap.get("stuPassNum"))) / stuNum * 100) + "%";
        map.put("passRate", passRate);
        numberOfPeopleDivided(map, paperId, stuNum);
        return map;
    }

    /**
     * @param paperId
     * @return
     */
    @Override
    public Map<String, Object> paperQuestionType(Integer paperId) {
        Map<String, Object> map = new HashMap<>();
        List<String> tapList = new ArrayList<>();
        List<Integer> dataList = new ArrayList<>();

        List<OrderPaperAnalysisVO> list = orderPaperAnalysisMapper.paperQuestionType(paperId);
        for (OrderPaperAnalysisVO vo : list) {
            String desc = DbEnumsUtil.getDesc(vo.getQuestionType());
            tapList.add(desc);
            dataList.add(vo.getQuestionTypeCount());
            vo.setQuestionType(desc);
        }
        map.put("tapList", tapList);
        map.put("dataList", dataList);
        map.put("list", list);
        return map;
    }


    /**
     * 试题分数分布
     */
    @Override
    public Map<String, Object> paperScoreDistribution(Integer paperId) {
        Map<String, Object> mapThis = new HashMap<>();
        //获取班级信息
        OrderPaper orderPaper = orderPaperMapper.selectOrderPaperById(paperId);
        List<TClass> tClasses = orderPaperMapper.selectClassByTopCatalogId(orderPaper.getTopCatalogId());
        //获取学生人数
        Integer stuNum = tStudentMapper
                .selectStudentNumByClassId(tClasses.stream().map(TClass::getId).collect(Collectors.toList()));
        numberOfPeopleDivided(mapThis, paperId, stuNum);
//        List<OrderPaperAnalysisVO> listThis = null;
//        Map<String, Object> mapThis = null;
//        Integer stuNumThis = null;
//        if (paperId != null) {
//            mapThis = new HashMap<>();
//            OrderPaper orderPaper = orderPaperMapper.selectOrderPaperById(paperId);
//            //获取班级信息
//            List<TClass> tClasses = orderPaperMapper.selectClassByTopCatalogId(orderPaper.getTopCatalogId());
//            //获取学生人数
//            stuNumThis = tStudentMapper
//                    .selectStudentNumByClassId(tClasses.stream().map(TClass::getId).collect(Collectors.toList()));
//            //获取学生答题试卷信息
//            listThis = orderPaperAnalysisMapper.selectAllUserPaperByPaperId(paperId);
//        } else {
//            listThis = list;
//            mapThis = map;
//            stuNumThis = stuNum;
//        }
//        numberOfPeopleDivided(listThis, mapThis, stuNumThis - listThis.size(), stuNumThis);
        return mapThis;
    }

    /**
     * 易错题top
     *
     * @param paperId
     * @return
     */
    @Override
    public Map<String, Object> fallibleQuestionTop(Integer paperId) {
        Map<String, Object> map = new HashMap<>();
        List<OrderPaperAnalysisVO> list = orderPaperAnalysisMapper.fallibleQuestionTop(paperId);
        for (OrderPaperAnalysisVO vo : list) {
            vo.setFallibleQuestionRateStr(df.format((float) vo.getFallibleQuestionCount() / vo.getSelectCount() * 100) + "%");
        }
        map.put("dataList", list);
        return map;
    }

    /**
     * 每道题选择人数
     *
     * @param paperId
     * @return
     */
    @Override
    public Map<String, Object> itemAnalysis(Integer paperId) {
        Map<String, Object> map = new HashMap<>();
        ArrayList<QuestionForAnalysisVo> dataList = new ArrayList<>();
        QuestionForAnalysisVo questionForAnalysisVo = null;
        OrderPaper orderPaper = orderPaperMapper.selectOrderPaperById(paperId);
        //获取班级信息
        List<TClass> tClasses = orderPaperMapper.selectClassByTopCatalogId(orderPaper.getTopCatalogId());
        //获取学生人数
        Integer stuNum = tStudentMapper
                .selectStudentNumByClassId(tClasses.stream().map(TClass::getId).collect(Collectors.toList()));
        List<QuestionForAnalysisVo> list = orderPaperAnalysisMapper.selectOrderQuestionByPaperId(paperId);
        List<OrderPaperAnalysisVO> answerList = orderPaperAnalysisMapper.selectOrderAnswer(paperId, list);
        Map<Integer, List<OrderPaperAnalysisVO>> answerMap = answerList.stream()
                .collect(Collectors.groupingBy(x -> x.getQuestionId()));
        for (QuestionForAnalysisVo vo : list) {
            Integer questionId = vo.getQuestionId();
            List<OrderPaperAnalysisVO> voList = answerMap.get(questionId);
            buildData(vo, voList, stuNum, orderPaper);
            dataList.add(vo);
        }
//        List<QuestionTopVO> topList = buildDataList(dataList);
        map.put("dataList", dataList);
//        map.put("topList", topList);
        map.put("stuNum", stuNum);
        map.put("paperName", orderPaper.getIntroduction());
        return map;
    }

    //组合前台试卷详情
    private List<QuestionTopVO> buildDataList(ArrayList<QuestionForAnalysisVo> dataList) {
        List<QuestionTopVO> list = new ArrayList<>();
        for (QuestionForAnalysisVo vo : dataList) {
            QuestionTopVO questionTopVO = new QuestionTopVO();
            questionTopVO.setQuestionId(vo.getQuestionId());
            questionTopVO.setQuestionType(DbEnumsUtil.getDesc(vo.getQuestionType()));
            questionTopVO.setPaperId(vo.getPaperId());
            questionTopVO.setStContent(vo.getStContent());
            List<QuestionTopDetailVO> detailVOS = new ArrayList<>();
            questionTopVO.setDetailVOS(detailVOS);
            //A选项
            String stSelectA = vo.getStSelectA();
            if (StringUtils.isNotBlank(stSelectA)) {
                QuestionTopDetailVO qvo = new QuestionTopDetailVO("A", stSelectA, vo.getStSelectAifTrue(),
                        vo.getStSelectAnum(), vo.getStSelectAproportion());
                detailVOS.add(qvo);
            }
            //B选项
            String stSelectB = vo.getStSelectB();
            if (StringUtils.isNotBlank(stSelectB)) {
                QuestionTopDetailVO qvo = new QuestionTopDetailVO("B", stSelectB, vo.getStSelectBifTrue(),
                        vo.getStSelectBnum(), vo.getStSelectBproportion());
                detailVOS.add(qvo);
            }
            //C选项
            String stSelectC = vo.getStSelectC();
            if (StringUtils.isNotBlank(stSelectC)) {
                QuestionTopDetailVO qvo = new QuestionTopDetailVO("C", stSelectC, vo.getStSelectCifTrue(),
                        vo.getStSelectCnum(), vo.getStSelectCproportion());
                detailVOS.add(qvo);
            }
            //D选项
            String stSelectD = vo.getStSelectD();
            if (StringUtils.isNotBlank(stSelectD)) {
                QuestionTopDetailVO qvo = new QuestionTopDetailVO("D", stSelectD, vo.getStSelectDifTrue(),
                        vo.getStSelectDnum(), vo.getStSelectDproportion());
                detailVOS.add(qvo);
            }
            //E选项
            String stSelectE = vo.getStSelectE();
            if (StringUtils.isNotBlank(stSelectE)) {
                QuestionTopDetailVO qvo = new QuestionTopDetailVO("E", stSelectE, vo.getStSelectEifTrue(),
                        vo.getStSelectEnum(), vo.getStSelectEproportion());
                detailVOS.add(qvo);
            }
            //F选项
            String stSelectF = vo.getStSelectF();
            if (StringUtils.isNotBlank(stSelectF)) {
                QuestionTopDetailVO qvo = new QuestionTopDetailVO("F", stSelectF, vo.getStSelectFifTrue(),
                        vo.getStSelectFnum(), vo.getStSelectFproportion());
                detailVOS.add(qvo);
            }
            //未选择
            String noSelect = vo.getNoSelect();
            if (StringUtils.isNotBlank(noSelect)) {
                QuestionTopDetailVO qvo = new QuestionTopDetailVO("未作答", noSelect, false,
                        vo.getNoSelectnum(), vo.getNoSelectFproportion());
                detailVOS.add(qvo);
            }
            list.add(questionTopVO);
        }
        return list;
    }

    /**
     * 学情分析top
     *
     * @param courseId
     * @param classId
     * @return
     */
    @Override
    public Map<String, Object> dataScreening(Integer courseId, Integer classId) {
        Map<String, Object> map = new HashMap<>(4);
        //视频学习总学时
        map.put("videoDuration", df.format((float) videoDuration(courseId, classId) / 60 / 60));
        //线上考核参与人数
        map.put("numberOfParticipants", numberOfParticipants(courseId, classId));
        //学生数量
        Integer stuNum = orderPaperAnalysisMapper.getStuNum(courseId, classId);
        //平均学习进度_____学生已经学习完的视频总数/（学生数量*视频数量）
        map.put("avgLearningProgress", avgLearningProgress(courseId, classId, stuNum));
        //测试及格率 所有及格人数/（总人数*试卷数量）
        map.put("passRate", passRate(courseId, classId, stuNum));
        return map;
    }

    /**
     * 学习进度
     *
     * @param courseId
     * @param classId
     * @return
     */
    @Override
    public Map<String, Object> rateOfLearning(Integer courseId, Integer classId) {
        Map<String, Object> map = new HashMap<>();
        List<StudyAnalysisVo> list = rateOfLearningList(courseId, classId, null, null);
        //计算每个学习进度人数
        int num1 = 0;
        int num2 = 0;
        int num3 = 0;
        int num4 = 0;
        for (StudyAnalysisVo vo : list) {
            BigDecimal progress = vo.getProgress() == null ? zero : vo.getProgress();
            vo.setProgressStr(df.format(progress) + "%");
            if (zero.compareTo(progress) <= 0 && twenty.compareTo(progress) >= 0) {
                num1++;
            }
            if (twentyOne.compareTo(progress) <= 0 && fifty.compareTo(progress) >= 0) {
                num2++;
            }
            if (fiftyOne.compareTo(progress) <= 0 && eighty.compareTo(progress) >= 0) {
                num3++;
            }
            if (eightyOne.compareTo(progress) <= 0 && oneHundred.compareTo(progress) >= 0) {
                num4++;
            }
        }
        map.put("dataList", list);
        List<EchartsVO> echartsVOS = new ArrayList<>();
        int sumNum = num1 + num2 + num3 + num4;
        echartsVOS.add(new EchartsVO(num1, progressStr1, new BigDecimal(df.format((float) num1 / sumNum * 100))));
        echartsVOS.add(new EchartsVO(num2, progressStr2, new BigDecimal(df.format((float) num2 / sumNum * 100))));
        echartsVOS.add(new EchartsVO(num3, progressStr3, new BigDecimal(df.format((float) num3 / sumNum * 100))));
        echartsVOS.add(new EchartsVO(num4, progressStr4, new BigDecimal(df.format((float) num4 / sumNum * 100))));
        map.put("echartsData", echartsVOS);
        return map;
    }

    @Override
    public Map<String, Object> rateOfLearningApp(Integer courseId, Integer classId, Integer pageNum, Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        List<StudyAnalysisVo> list = rateOfLearningList(courseId, classId, pageNum, pageSize);
        for (StudyAnalysisVo vo : list) {
            BigDecimal progress = vo.getProgress() == null ? zero : vo.getProgress();
            vo.setProgressStr(df.format(progress) + "%");
        }
        PageInfo pageInfo = new PageInfo<>(list);
        map.put("dataList", pageInfo);
        return map;
    }

    @Override
    public Map<String, Object> rateOfLearningEcharts(Integer courseId, Integer classId) {
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> map1 = rateOfLearning(courseId, classId);
        map.put("echartsData", map1.get("echartsData"));
        return map;
    }

    private List<StudyAnalysisVo> rateOfLearningList(Integer courseId, Integer classId, Integer pageNum, Integer pageSize) {
        //获取视频总数
        Integer videoCount = orderPaperAnalysisMapper.getVideoCount(courseId, classId);
        //计算每个学生学习进度 【传入视频总数】
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<StudyAnalysisVo> list = orderPaperAnalysisMapper.everyOneProgress(courseId, classId, videoCount, timeLimit);
        return list;
    }

    /**
     * 考核完成情况 左右
     *
     * @param paramVo
     * @return
     */
    @Override
    public Map<String, Object> assessmentCompletion(StudyAnalysisParamVo paramVo) {
        Map<String, Object> map = new HashMap<>();
        buildAssessmentCompletionEcharts(map, paramVo);
        List<StudyAnalysisVo> list = orderPaperAnalysisMapper.getPaperStuProgress(paramVo);
        //获取所有参加考试学生
        List<StudyAnalysisVo> learnedList = new ArrayList<>();
        //获取所有未参加考试学生
        List<StudyAnalysisVo> notlearnedList = new ArrayList<>();
        for (StudyAnalysisVo studyAnalysisVo : list) {
            if (StringUtils.isNotBlank(studyAnalysisVo.getUserStudyInfo())) {
                learnedList.add(studyAnalysisVo);
            } else {
                notlearnedList.add(studyAnalysisVo);
            }
        }
        map.put("learnedList", learnedList);
        map.put("notlearnedList", notlearnedList);
        List<Integer> paperIdList = orderPaperAnalysisMapper.getPaperIdList(paramVo);
        float averageScore = orderPaperAnalysisMapper.getAvgScore(paramVo);
        map.put("averageScore", df.format(averageScore / (CollectionUtil.isEmpty(paperIdList) ? 0 : paperIdList.size())));
        return map;
    }

    @Override
    public Map<String, Object> assessmentCompletionEcharts(StudyAnalysisParamVo paramVo) {
        Map<String, Object> map = new HashMap<>();
        buildAssessmentCompletionEcharts(map, paramVo);
        return map;
    }

    @Override
    public Map<String, Object> assessmentCompletionApp(StudyAnalysisParamVo paramVo, Integer pageNum, Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        paramVo.setCatalogIdList(orderPaperAnalysisMapper.getCatalogIdList(paramVo.getCourseId(), paramVo.getClassId()));
        List<Integer> paperIdList = orderPaperAnalysisMapper.getPaperIdList(paramVo);
        float averageScore = orderPaperAnalysisMapper.getAvgScore(paramVo);
        map.put("averageScore", df.format(averageScore / (CollectionUtil.isEmpty(paperIdList) ? 0 : paperIdList.size())));
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<StudyAnalysisVo> list = orderPaperAnalysisMapper.getPaperStuProgress(paramVo);
        PageInfo pageInfo = new PageInfo(list);
        map.put("dataList", pageInfo);
        return map;
    }

    private void buildAssessmentCompletionEcharts(Map<String, Object> map, StudyAnalysisParamVo paramVo) {
        paramVo.setCatalogIdList(orderPaperAnalysisMapper.getCatalogIdList(paramVo.getCourseId(), paramVo.getClassId()));
        List<EchartsVO> echartsVOS = orderPaperAnalysisMapper.getPaperStuNum(paramVo);
        List<String> tapList = new ArrayList<>();
        List<Integer> dataList = new ArrayList<>();
        for (EchartsVO echartsVO : echartsVOS) {
            tapList.add(echartsVO.getName());
            dataList.add(echartsVO.getValue());
        }
        map.put("tapList", tapList);
        map.put("dataList", dataList);
    }


    /**
     * 视频学习情况
     *
     * @param paramVo
     * @return
     */
    @Override
    public Map<String, Object> videoLearning(StudyAnalysisParamVo paramVo) {
        Map<String, Object> map = new HashMap<>();
        buildVideoLearningEcharts(map, paramVo);
        List<StudyAnalysisVo> list = orderPaperAnalysisMapper.getVideoStuProgress(paramVo, timeLimit, null);
        for (StudyAnalysisVo vo : list) {
            String userStudyInfo = vo.getUserStudyInfo();
            String s = null;
            if (StringUtils.isNotEmpty(userStudyInfo)) {
                s = second2Time(Long.valueOf(userStudyInfo));
            }
            vo.setUserStudyInfo(s);
        }
        List<StudyAnalysisVo> learnedList = new ArrayList<>();
        List<StudyAnalysisVo> notlearnedList = new ArrayList<>();
        for (StudyAnalysisVo vo : list) {
            if (StringUtils.isNotEmpty(vo.getUserStudyInfo())) {
                learnedList.add(vo);
            } else {
                notlearnedList.add(vo);
            }
        }
        map.put("learnedList", learnedList);
        map.put("notlearnedList", notlearnedList);
        return map;
    }

    @Override
    public Map<String, Object> videoLearningEcharts(StudyAnalysisParamVo paramVo) {
        Map<String, Object> map = new HashMap<>();
        buildVideoLearningEcharts(map, paramVo);
        return map;
    }

    @Override
    public Map<String, Object> videoLearningApp(StudyAnalysisParamVo paramVo, Integer pageNum, Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        paramVo.setCatalogIdList(orderPaperAnalysisMapper.getCatalogIdList(paramVo.getCourseId(), paramVo.getClassId()));
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<StudyAnalysisVo> list = orderPaperAnalysisMapper.getVideoStuProgress(paramVo, timeLimit, paramVo.getIfLearn());
        PageInfo pageList = new PageInfo<>(list);
        map.put("dataList", pageList);
        return map;
    }


    private void buildVideoLearningEcharts(Map<String, Object> map, StudyAnalysisParamVo paramVo) {
        paramVo.setCatalogIdList(orderPaperAnalysisMapper.getCatalogIdList(paramVo.getCourseId(), paramVo.getClassId()));
        List<EchartsVO> echartsVOS = orderPaperAnalysisMapper.getVideoStuNum(paramVo, timeLimit);
        List<String> tapList = new ArrayList<>();
        List<Integer> dataList = new ArrayList<>();
        for (EchartsVO echartsVO : echartsVOS) {
            tapList.add(echartsVO.getName());
            dataList.add(echartsVO.getValue());
        }
        map.put("tapList", tapList);
        map.put("dataList", dataList);
    }

    /**
     * 内容榜单
     *
     * @param paramVo
     * @return
     */
    @Override
    public Map<String, Object> contentList(StudyAnalysisParamVo paramVo) {
        Map<String, Object> map = new HashMap<>(2);
        paramVo.setCatalogIdList(orderPaperAnalysisMapper.getCatalogIdList(paramVo.getCourseId(), paramVo.getClassId()));
        //List<Integer> paperIdList = orderPaperAnalysisMapper.getPaperIdList(paramVo);
        List<Integer> userPaperIdList = orderPaperAnalysisMapper.getUserPaperIdList(paramVo);
        //获取学生人数
        //Integer stuNum = tStudentMapper
        //        .selectStudentNumByClassId(new ArrayList<Integer>() {{
        //            add(paramVo.getClassId());
        //        }});
        Integer sumCount = orderPaperAnalysisMapper.selectQuestionTopCount(paramVo, userPaperIdList);
        List<EchartsVO> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userPaperIdList) && sumCount != null && !sumCount.equals(0)) {
            list = orderPaperAnalysisMapper.selectQuestionTop(paramVo, userPaperIdList);
            for (EchartsVO vo : list) {
                int value = vo.getValue();
                String passRate = df.format((1 - (float) value / sumCount) * 100) + "%";
                vo.setPercentage(passRate);
            }
        }
        map.put("dataList", list);
        return map;
    }


    /**
     * 参与率最高的讨论主题TOP3
     *
     * @param paramVo
     * @return
     */
    @Override
    public Map<String, Object> talkTop(StudyAnalysisParamVo paramVo) {
        Map<String, Object> map = new HashMap<>();
        paramVo.setCatalogIdList(orderPaperAnalysisMapper.getCatalogIdList(paramVo.getCourseId(), paramVo.getClassId()));
        List<EchartsVO> list = orderPaperAnalysisMapper.talkTop(paramVo);
        map.put("dataList", list);
        return map;
    }

    //app学习统计top
    @Override
    public Map<String, Object> learningStatistics(LearningStatisticsDto paramVo) {
        Map<String, Object> map = new HashMap<>();
        //视频时长
        Long videoDuration = orderPaperAnalysisMapper.getDurationVideoByUserId(paramVo);
        //试卷时长，累计答题，答对题数
        LearningStatisticsVO vo = orderPaperAnalysisMapper.getDurationPaperByUserId(paramVo);

        int totalCorrect = 0, allNum = 0, duration = 0, answerAll = 0;
        if (vo != null) {
            totalCorrect = vo.getTotalCorrect();
            allNum = vo.getAllNum();
            duration = vo.getDuration();
            answerAll = vo.getAnswerAll();
        }

        map.put("videoDuration", (videoDuration == null ? 0 : videoDuration) / 60);
        map.put("paperDuration", df.format((float) duration / 1000 / 60));
        map.put("answerAll", answerAll);
        map.put("totalCorrect", totalCorrect);
        if (totalCorrect == 0 || allNum == 0) {
            map.put("precision", "0.00%");
        } else {
            String precision = df.format((float) totalCorrect / allNum * 100) + "%";
            map.put("precision", precision);
        }
        return map;
    }

    //app错题本
    @Override
    public Map<String, Object> wrongTitleBook(LearningStatisticsDto paramVo) {
        Map<String, Object> map = new HashMap<>();
        Integer pageNum = paramVo.getPageNum() == null ? 0 : paramVo.getPageNum();
        Integer pageSize = paramVo.getPageSize() == null ? 10 : paramVo.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        List<LearningStatisticsBVO> list = orderPaperAnalysisMapper.wrongTitleBook(paramVo);
        PageInfo<LearningStatisticsBVO> pageList = new PageInfo<>(list);
        map.put("dataList", pageList);
        return map;
    }

    //app错题排行榜
    @Override
    public Map<String, Object> wrongQuestionRanking(LearningStatisticsDto paramVo) {
        Map<String, Object> map = new HashMap<>();
        String schoolName;
        TSchool tSchool = tSchoolMapper.selectTSchoolById(paramVo.getSchoolId());
        if (tSchool != null && StringUtils.isNotEmpty(tSchool.getSchoolName())) {
            schoolName = tSchool.getSchoolName();
        } else {
            schoolName = "平台";
        }
//        Integer pageNum = paramVo.getPageNum() == null ? 0 : paramVo.getPageNum();
//        Integer pageSize = paramVo.getPageSize() == null ? 10 : paramVo.getPageSize();
//        PageHelper.startPage(pageNum, pageSize);
        List<LearningStatisticsAVO> list = orderPaperAnalysisMapper.wrongQuestionRanking(paramVo);
        for (LearningStatisticsAVO vo : list) {
            vo.setSchoolName(schoolName);
        }
//        PageInfo<LearningStatisticsAVO> pageList = new PageInfo<>(list);
        map.put("dataList", list);
        return map;
    }

    //app答对题排行榜
    @Override
    public Map<String, Object> correctQuestionsRanking(LearningStatisticsDto paramVo) {
        buildTime(paramVo);
        Map<String, Object> map = new HashMap<>();
        //获取前10排名
        List<LearningStatisticsCVO> list = orderPaperAnalysisMapper.correctQuestionsRanking(paramVo);
        //获取自己排名
        LearningStatisticsCVO vo = orderPaperAnalysisMapper.oneselfRanking(paramVo);
        map.put("dataList", list);
        map.put("oneselfRanking", vo);
        return map;
    }

    //正确率排行榜
    @Override
    public Map<String, Object> accuracyRanking(LearningStatisticsDto paramVo) {
        buildTime(paramVo);
        Map<String, Object> map = new HashMap<>();
        //获取前10排名
        List<LearningStatisticsEVO> list = orderPaperAnalysisMapper.accuracyRanking(paramVo);
        for (LearningStatisticsEVO vo : list) {
            vo.setCorrectRateStr(df.format(vo.getCorrectRate() == null ? 0 : vo.getCorrectRate()) + "%");
        }
        //获取自己排名
        LearningStatisticsEVO vo = orderPaperAnalysisMapper.oneselfAccuracyRanking(paramVo);
        vo.setCorrectRateStr(df.format(vo.getCorrectRate() == null ? 0 : vo.getCorrectRate()) + "%");
        map.put("dataList", list);
        map.put("oneselfRanking", vo);
        return map;
    }

    //练习时长排行榜
    @Override
    public Map<String, Object> exerciseDurationRanking(LearningStatisticsDto paramVo) {
        buildTime(paramVo);
        Map<String, Object> map = new HashMap<>();
        //获取前10排名
        List<LearningStatisticsDVO> list = orderPaperAnalysisMapper.exerciseDurationRanking(paramVo);
        for (LearningStatisticsDVO learningStatisticsDVO : list) {
            learningStatisticsDVO.setDuration(df.format((float) Integer.valueOf(learningStatisticsDVO.getDuration()) / 1000));
        }
        //获取自己排名
        LearningStatisticsDVO vo = orderPaperAnalysisMapper.oneselfExerciseDurationRanking(paramVo);
        vo.setDuration(df.format((float) Integer.valueOf(vo.getDuration()) / 1000));
        map.put("dataList", list);
        map.put("oneselfRanking", vo);
        return map;
    }

    //错题本开始复习按钮
    @Override
    public Map<String, Object> selectWrongQuestions(Integer paperId, Integer userId) {
        Map<String, Object> map = new HashMap<>();
        List<SysOrderQuestionVO> list = OrderWrongAnswerMapper.selectWrongQuestions(paperId, userId);
        map.put("dataList", list);
        return map;
    }

    @Override
    public void subWrongQuestions(List<Integer> ids) {
        OrderWrongAnswerMapper.delByIds(ids);
    }


    //通过属性去重
//    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
//        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
//        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
//    }

    /**
     * @param second 秒
     * @description: 秒转换为时分秒 HH:mm:ss 格式 仅当小时数大于0时 展示HH
     * @return: {@link String}
     * @author: zcp
     * @date: 2022-05-08 13:55:17
     */
    private String second2Time(Long second) {
        if (second == null || second < 0) {
            return "00:00";
        }

        long h = second / 3600;
        long m = (second % 3600) / 60;
        long s = second % 60;
        String str = "";
        if (h > 0) {
            str = (h < 10 ? ("0" + h) : h) + ":";
        }
        str += (m < 10 ? ("0" + m) : m) + ":";
        str += (s < 10 ? ("0" + s) : s);
        return str;

    }


    /**
     * 视频学习总学时
     *
     * @return
     */
    private int videoDuration(Integer courseId, Integer classId) {
        Integer count = orderPaperAnalysisMapper.videoDuration(courseId, classId);
        return count == null ? 0 : count;
    }

    /**
     * 线上考核参与人数
     *
     * @return
     */
    private int numberOfParticipants(Integer courseId, Integer classId) {
        Integer count = orderPaperAnalysisMapper.numberOfParticipants(courseId, classId);
        return count == null ? 0 : count;
    }

    /**
     * 平均学习进度_____学生已经学习完的视频总数/（学生数量*视频数量）
     *
     * @return
     */
    private String avgLearningProgress(Integer courseId, Integer classId, Integer stuNum) {
        if (stuNum == null || stuNum.equals(0)) {
            return "0.00%";
        }
        //学生已经学完的视频总数
        Integer count = orderPaperAnalysisMapper.getStudyOverCount(courseId, classId, timeLimit);
        if (count == null || count.equals(0)) {
            return "0.00%";
        }
        //课堂视频总数
        Integer videoNum = orderPaperAnalysisMapper.getCourseVideoNum(courseId, classId);
        if (videoNum == null || videoNum.equals(0)) {
            return "0.00%";
        }
        String passRate = df.format((float) count / (videoNum * stuNum) * 100) + "%";
        return passRate;
    }

    /**
     * 测试及格率 所有及格人数/（总人数*试卷数量）
     *
     * @return
     */
    private String passRate(Integer courseId, Integer classId, Integer stuNum) {
        if (stuNum == null || stuNum.equals(0)) {
            return "0.00%";
        }
        int passStuNum = 0;
        //获取学生的考试成绩
        List<StudyAnalysisVo> list = orderPaperAnalysisMapper.getStudentScore(courseId, classId);
        if (Collections.isEmpty(list)) {
            return "0.00%";
        }
        //获取所有试卷的及格分数
        List<Integer> catalogIdList = orderPaperAnalysisMapper.getCatalogIdList(courseId, classId);
        if (Collections.isEmpty(catalogIdList)) {
            return "0.00%";
        }
        List<StudyAnalysisVo> paperPassScoreList = orderPaperAnalysisMapper.getPaperPassScore(catalogIdList);
        if (Collections.isEmpty(paperPassScoreList)) {
            return "0.00%";
        }
        //计算及格总人数
        Map<Integer, List<StudyAnalysisVo>> answerMap = list.stream().collect(Collectors.groupingBy(x -> x.getDataKey()));
        for (StudyAnalysisVo vo : paperPassScoreList) {
            List<StudyAnalysisVo> answerVos = answerMap.get(vo.getDataKey());
            if (!Collections.isEmpty(answerVos)) {
                for (StudyAnalysisVo answerVo : answerVos) {
                    if (answerVo.getDataValue().compareTo(vo.getDataValue()) < 0) {
                        passStuNum++;
                    }
                }
            }
        }
        //试卷数量
        int size = paperPassScoreList.size();
        String passRate = df.format((float) passStuNum / (stuNum * size) * 100) + "%";
        return passRate;
    }


    private void buildData(QuestionForAnalysisVo vo, List<OrderPaperAnalysisVO> voList, Integer stuNum, OrderPaper orderPaper) {
        int sumSelectCount = voList.size();
        String stAnswer = vo.getStAnswer();
        //分值DbEnumsUtil
        String questionType = vo.getQuestionType();
        switch (questionType) {
            case "1":
                vo.setScore(orderPaper.getSingleScore());
                break;
            case "2":
                vo.setScore(orderPaper.getJudgmentScore());
                break;
            case "3":
                vo.setScore(orderPaper.getManyScore());
                break;
            case "4":
                vo.setScore(orderPaper.getAnswSore());
                break;
            default:
                break;
        }
        vo.setStSelectAproportion(zero_0);
        vo.setStSelectBproportion(zero_0);
        vo.setStSelectCproportion(zero_0);
        vo.setStSelectDproportion(zero_0);
        vo.setStSelectEproportion(zero_0);
        vo.setStSelectFproportion(zero_0);
        int selectCountA = 0, selectCountB = 0, selectCountC = 0, selectCountD = 0, selectCountE = 0, selectCountF = 0;

        if (questionType.equals("1") || questionType.equals("2") || questionType.equals("3")) {
            //未作答
            vo.setNoSelectnum(stuNum - sumSelectCount);
            if (StringUtils.isNotEmpty(stAnswer)) {
                vo.setStSelectAifTrue(stAnswer.contains("A"));
                vo.setStSelectBifTrue(stAnswer.contains("B"));
                vo.setStSelectCifTrue(stAnswer.contains("C"));
                vo.setStSelectDifTrue(stAnswer.contains("D"));
                vo.setStSelectEifTrue(stAnswer.contains("E"));
                vo.setStSelectFifTrue(stAnswer.contains("F"));
            }
            for (OrderPaperAnalysisVO orderPaperAnalysisVO : voList) {
                String answer = orderPaperAnalysisVO.getAnswer();
                if (answer.contains("A")) {
                    selectCountA++;
                }
                if (answer.contains("B")) {
                    selectCountB++;
                }
                if (answer.contains("C")) {
                    selectCountC++;
                }
                if (answer.contains("D")) {
                    selectCountD++;
                }
                if (answer.contains("E")) {
                    selectCountE++;
                }
                if (answer.contains("F")) {
                    selectCountF++;
                }
            }
            //A选项
            vo.setStSelectAnum(selectCountA);
            String rateA = df.format((float) selectCountA / stuNum * 100);
            vo.setStSelectAproportion(new BigDecimal(rateA));

            //B选项
            vo.setStSelectBnum(selectCountB);
            String rateB = df.format((float) selectCountB / stuNum * 100);
            vo.setStSelectBproportion(new BigDecimal(rateB));

            //C选项
            vo.setStSelectCnum(selectCountC);
            String rateC = df.format((float) selectCountC / stuNum * 100);
            vo.setStSelectCproportion(new BigDecimal(rateC));

            //D选项
            vo.setStSelectDnum(selectCountD);
            String rateD = df.format((float) selectCountD / stuNum * 100);
            vo.setStSelectDproportion(new BigDecimal(rateD));

            //E选项
            vo.setStSelectEnum(selectCountE);
            String rateE = df.format((float) selectCountE / stuNum * 100);
            vo.setStSelectEproportion(new BigDecimal(rateE));

            //F选项
            vo.setStSelectFnum(selectCountF);
            String rateF = df.format((float) selectCountF / stuNum * 100);
            vo.setStSelectFproportion(new BigDecimal(rateF));

            String rate = df.format((float) vo.getNoSelectnum() / stuNum * 100);
            vo.setNoSelectFproportion(new BigDecimal(rate));
        } else if (questionType.equals("5")) {

        }

    }


    /**
     * 计算各个分段人数
     */
    private void numberOfPeopleDivided(Map<String, Object> map, Integer paperId, Integer stuNum) {
        Map<String, Object> mapVos = orderPaperAnalysisMapper.numberOfPeopleDivided(paperId);
        List<EchartsVO> echartsVOS = new ArrayList<>();
        for (String s : mapVos.keySet()) {
            Integer num = Integer.valueOf(String.valueOf(mapVos.get(s)));
            String percentage = df.format((float) num / stuNum * 100) + "%";
            echartsVOS.add(new EchartsVO(num, s, percentage));
        }
        map.put("numberOfPeopleDivided", echartsVOS);

//        int num1 = 0;
//        int num2 = 0;
//        int num3 = 0;
//        int num4 = 0;
//        int num5 = 0;
//        for (OrderPaperAnalysisVO vo : list) {
//            BigDecimal score = vo.getScore();
//            //计算各个分数段人数
//            if (zero.compareTo(score) <= 0 && fiftyNine.compareTo(score) >= 0) {
//                num1++;
//            } else if (sixty.compareTo(score) <= 0 && eighty.compareTo(score) >= 0) {
//                num2++;
//            } else if (eightyOne.compareTo(score) <= 0 && ninety.compareTo(score) >= 0) {
//                num3++;
//            } else if (ninetyOne.compareTo(score) <= 0 && ninetyNine.compareTo(score) >= 0) {
//                num4++;
//            } else if (oneHundred.compareTo(score) == 0) {
//                num5++;
//            }
//        }
//        //存储各个分段人数
//        List<EchartsVO> echartsVOS = new ArrayList<>();
//        num1 = num1 + unTestStuNum;
//        String percentage1 = df.format((float) num1 / stuNum * 100) + "%";
//        echartsVOS.add(new EchartsVO(num1, str1, percentage1));
//        String percentage2 = df.format((float) num2 / stuNum * 100) + "%";
//        echartsVOS.add(new EchartsVO(num2, str2, percentage2));
//        String percentage3 = df.format((float) num3 / stuNum * 100) + "%";
//        echartsVOS.add(new EchartsVO(num3, str3, percentage3));
//        String percentage4 = df.format((float) num4 / stuNum * 100) + "%";
//        echartsVOS.add(new EchartsVO(num4, str4, percentage4));
//        String percentage5 = df.format((float) num5 / stuNum * 100) + "%";
//        echartsVOS.add(new EchartsVO(num5, str5, percentage5));
//        map.put("numberOfPeopleDivided", echartsVOS);
    }

    //计算开始结束时间
    private void buildTime(LearningStatisticsDto paramVo) {
        Integer dateType = paramVo.getDateType();
        Date endDate = new Date();
        Date startDate = DateUtil.diffDate(endDate, dateType);
        paramVo.setStartDate(startDate);
        paramVo.setEndDate(endDate);
    }
}
